package ants.p2p.gui;
import java.util.HashMap;
public class ConnectingThreadManager {
	HashMap threadMap=new HashMap();
	Object objLock=new Object();
	ConnectionManager theCMer;
	ConnectingThreadManager(ConnectionManager cm)
	{
		theCMer=cm;
	}
	public void ConnectTo(String sRemote,int port,String sURI)
	{
		theCMer.ConnectTo(this,sRemote, port, sURI);
	}
	public void Add(String sURI,String sHostIp,String sSameSubnetIp,int port)
	{
		synchronized(objLock)
		{
			ConnectingThread theThread=(ConnectingThread)threadMap.get(sURI);
			if(theThread==null)
			{
				ConnectingThread newThread=new ConnectingThread(this,sURI,sHostIp,sSameSubnetIp,port);
					threadMap.put(sURI, newThread);
				newThread.DoNext();
			}
		}
	}
	public void DoNext(String sURI)
	{
		synchronized(objLock)
		{
			ConnectingThread theThread=(ConnectingThread)threadMap.get(sURI);
			if(theThread!=null)theThread.DoNext();
		}
		
	}
	public boolean contains(String sURI)
	{
		synchronized(objLock)
		{
			return threadMap.containsKey(sURI);
		}
	}
	public void remove(String sURI)
	{
		synchronized(objLock)
		{
			threadMap.remove(sURI);
		}
	}
	public void clear()
	{
		synchronized(objLock)
		{
			threadMap.clear();
		}
	}
}
class ConnectingThread {
	public ConnectingThread(ConnectingThreadManager theManager_,String sURI_,String sHostIp_,String sSameSubnetIp_,int port_)
	{
		sURI=sURI_;
		theManager=theManager_;
		port=port_;
		sSameSubnetIp=sSameSubnetIp_;
		sHostIp=sHostIp_;
		state=NOTCONNECTING;
	}
	public void DoNext()
	{
		switch(state)
		{
		case NOTCONNECTING:
			state=SUBNETCONNECTING;
			if(isSTUNTServer())
			{
				if( sSameSubnetIp!=null && sSameSubnetIp.length()>0 )
				{
					theManager.ConnectTo(sSameSubnetIp, Math.abs(port), sURI);
					//must be return or break;
					return;
				}
			}
			DoNext();
			break;
		case SUBNETCONNECTING:
			state=DIRECTCONNECTING;
			theManager.ConnectTo(sHostIp, Math.abs(port), sURI);
			break;
		case DIRECTCONNECTING:
			state=FINALCONNECTING;
			if(isSTUNTServer())
			{
				theManager.ConnectTo(sURI+"@"+sHostIp, port, sURI);
			}
			else
			{
				theManager.remove(sURI);
			}
			break;
		case FINALCONNECTING:
			theManager.remove(sURI);
			break;
		}
		
	}
	private boolean isSTUNTServer()
	{
		return port<=0;
	}
	int state;
	int port;
	String sHostIp;
	String sSameSubnetIp;
	String sURI;
	ConnectingThreadManager theManager;
	private static final int NOTCONNECTING=-1;
	private static final int SUBNETCONNECTING=0;
	private static final int DIRECTCONNECTING=1;
	private static final int FINALCONNECTING=2;
}